import Page from "@src/components/Page";
import {
  IPackageSearchMetadata,
  ISearchPackagesRequest,
  SearchPackagesRequest,
} from "@src/services/client";
import clientInstance from "@src/services/instance";
import {
  BootstrapIcon,
  BsButton,
  FcCheckBox,
  FcForm,
  FcFormControl,
  FcFormItem,
  FcFormItemLayout,
  FcFormSubmit,
  FcInput,
  FcInputGroup,
  FormControl,
  FormField,
  IFormInstance,
  Loading,
  SolidModal,
  Table,
  utils,
  ValueAccessor,
} from "solid-fire-controls";
import { createResource, createSignal, JSXElement, Show } from "solid-js";
import PackageSourceSelect from "../package-source/Select";
import { Modal } from "bootstrap";
import PackageFormPart from "./PackageFormPart";
import FcImage from "@src/components/FcImage";
import DownloadPackage, { DownloadPackageProps } from "./Download";

const PackageList = () => {
  const [modal, setModal] = createSignal<Modal | undefined>(undefined);
  const [modalTitle, setModalTitle] = createSignal<JSXElement>("");
  const [form, setForm] = createSignal<IFormInstance | undefined>(undefined);

  const [downloadModal, setDownloadModal] = createSignal<Modal | undefined>(
    undefined
  );
  const [downloadForm, setDownloadForm] = createSignal<
    IFormInstance | undefined
  >(undefined);
  const [downloadModalTitle, setDownloadModalTitle] =
    createSignal<JSXElement>("");

  const loadPackageList = (req: SearchPackagesRequest) =>
    clientInstance.package.searchPackages(req);

  const [request, setRequest] = createSignal<SearchPackagesRequest>(
    SearchPackagesRequest.fromJS({ pageIndex: 1, pageSize: 20 })
  );

  const [pageSize, setPageSize] = createSignal(20);

  const [packageList, { mutate, refetch }] = createResource(
    request,
    loadPackageList
  );

  const handleSearch = (value: ISearchPackagesRequest) => {
    setRequest((v) =>
      SearchPackagesRequest.fromJS({
        ...v,
        ...value,
        pageIndex: 1,
      })
    );
  };

  const handleMoveToPrevPage = () => {
    setRequest((v) => {
      return v.pageIndex && v.pageIndex > 1
        ? SearchPackagesRequest.fromJS({ ...v, pageIndex: v.pageIndex - 1 })
        : v;
    });
  };

  const handleMoveToNextPage = () => {
    if ((packageList()?.length ?? 0) >= (request()?.pageSize ?? 0)) {
      setRequest((v) => {
        return SearchPackagesRequest.fromJS({
          ...v,
          pageIndex: (v.pageIndex ?? 1) + 1,
        });
      });
    }
  };

  const handlePageSizeChanged = (pageSize: number) => {
    setRequest((v) =>
      pageSize !== v.pageSize
        ? SearchPackagesRequest.fromJS({
            ...v,
            pageIndex: 1,
            pageSize: pageSize,
          })
        : v
    );
  };

  const setupModalTitle = (value: IPackageSearchMetadata) => {
    setModalTitle(
      <>
        <Show when={utils.IsNotWhitespaceString(value.iconUrl)}>
          <FcImage
            value={value.iconUrl ?? ""}
            style={{ height: "48px" }}
            classList={{ "me-1": true }}
          ></FcImage>
        </Show>
        <span style={{ "text-wrap": "wrap", "overflow-wrap": "anywhere" }}>
          {value.title}
        </span>
      </>
    );
  };

  const setupDownloadModalTitle = (value: IPackageSearchMetadata) => {
    setDownloadModalTitle(
      <>
        <span>下载 | </span>
        <Show when={utils.IsNotWhitespaceString(value.iconUrl)}>
          <FcImage
            value={value.iconUrl ?? ""}
            style={{ height: "48px" }}
            classList={{ "me-1": true }}
          ></FcImage>
        </Show>
        <span style={{ "text-wrap": "wrap", "overflow-wrap": "anywhere" }}>
          {value.title}
        </span>
      </>
    );
  };

  const showDetail = (value: IPackageSearchMetadata) => {
    setupModalTitle(value);
    form()?.setValue(value);
    modal()?.show();
  };

  const downloadPackage = (
    value: IPackageSearchMetadata,
    packageSourceName?: string
  ) => {
    setupDownloadModalTitle(value);
    const props: DownloadPackageProps = {
      packageId: value.identity?.id!,
      packageSourceName: packageSourceName!,
    };
    downloadForm()?.setValue(props);
    downloadModal()?.show();
  };

  return (
    <Page>
      <FcForm
        value={{}}
        onSubmit={handleSearch}
        classList={["row", "g-3", "mb-3"]}
      >
        <FcFormItemLayout template={"horizontal"}>
          <FcFormItem name="keyWord" classList={["col-4"]}>
            <FcFormControl
              control={FcInput}
              controlProps={{ placeholder: "请输入搜索关键字..." }}
            ></FcFormControl>
          </FcFormItem>
          <FcFormItem name={"packageSourceName"} classList={["col-1"]}>
            <FcFormControl control={PackageSourceSelect}></FcFormControl>
          </FcFormItem>
          <FcFormItem name={"includePreRelease"} classList={["col-1"]}>
            <FcFormControl
              control={FcCheckBox}
              controlProps={{ children: "包含预发行" }}
            ></FcFormControl>
          </FcFormItem>
          <FcFormItem classList={["col-2"]}>
            <div>
              <FcFormSubmit>搜索</FcFormSubmit>
            </div>
          </FcFormItem>
        </FcFormItemLayout>
      </FcForm>
      <div class="row">
        <Loading show={packageList.loading}>
          <div class="col-12">
            <Table
              responsive
              hover
              datas={packageList()}
              columns={[
                {
                  type: "index",
                },
                {
                  name: "iconUrl",
                  label: "Icon",
                  children(data, column, index) {
                    return <img src={data.iconUrl} height={"24px"}></img>;
                  },
                },
                {
                  name: "title",
                  label: "Title",
                },
                {
                  label: " ",
                  width: 50,
                  children(data, column, index) {
                    return (
                      <BootstrapIcon
                        icon="search"
                        onClick={() => showDetail(data)}
                        style={{ cursor: "pointer" }}
                      ></BootstrapIcon>
                    );
                  },
                },
                {
                  label: " ",
                  width: 50,
                  children(data, column, index) {
                    return (
                      <BootstrapIcon
                        icon="download"
                        onClick={() =>
                          downloadPackage(data, request().packageSourceName)
                        }
                        style={{ cursor: "pointer" }}
                      ></BootstrapIcon>
                    );
                  },
                },
                {
                  label: "Version",
                  width: 200,
                  children(data, column, index) {
                    return data.identity?.version?.version;
                  },
                },
                {
                  label: "Download",
                  name: "downloadCount",
                  width: 100,
                },
                {
                  name: "summary",
                  label: "Summary",
                  width: 300,
                },
                {
                  name: "tags",
                  label: "Tags",
                },
                {
                  name: "authors",
                  label: "Authors",
                },
              ]}
            ></Table>
          </div>
          <div class="col-12 d-flex gap-1 justify-content-center">
            <FcInputGroup style={{ width: "400px" }}>
              <BsButton
                classList={{ disabled: (request().pageIndex ?? 1) <= 1 }}
                onclick={handleMoveToPrevPage}
                disabled={request().pageIndex! <= 1}
                style={{ width: "80px" }}
              >
                上一页
              </BsButton>
              <FcInputGroup.Text>第{request().pageIndex}页</FcInputGroup.Text>
              <FcInputGroup.Text>每页</FcInputGroup.Text>
              <FcInput
                value={pageSize()}
                type="number"
                onValueChanged={setPageSize}
                onBlur={() => handlePageSizeChanged(pageSize())}
                onMouseEnter={() => handlePageSizeChanged(pageSize())}
                style={{ width: "40px" }}
              ></FcInput>
              <FcInputGroup.Text>条</FcInputGroup.Text>
              <BsButton
                classList={{
                  disabled:
                    (packageList()?.length ?? 0) < (request()?.pageSize ?? 0),
                }}
                onclick={handleMoveToNextPage}
                disabled={
                  (packageList()?.length ?? 0) < (request()?.pageSize ?? 0)
                }
                style={{ width: "80px" }}
              >
                下一页
              </BsButton>
            </FcInputGroup>
          </div>
        </Loading>
      </div>
      <SolidModal
        onRef={setModal}
        onHidden={() => {
          form()?.setValue({});
          setModalTitle("");
        }}
      >
        <SolidModal.Header>
          <SolidModal.Title>{modalTitle()}</SolidModal.Title>
          <SolidModal.CloseButton></SolidModal.CloseButton>
        </SolidModal.Header>
        <SolidModal.Body>
          <FcForm onRef={setForm} disabled readonly>
            <PackageFormPart></PackageFormPart>
          </FcForm>
        </SolidModal.Body>
      </SolidModal>

      <SolidModal onRef={setDownloadModal}>
        <SolidModal.Header>
          <SolidModal.Title>{downloadModalTitle()}</SolidModal.Title>
          <SolidModal.CloseButton></SolidModal.CloseButton>
        </SolidModal.Header>
        <SolidModal.Body>
          <FcForm onRef={setDownloadForm}>
            <FormField>
              <FormControl
                control={(ctx: ValueAccessor<DownloadPackageProps>) => (
                  <DownloadPackage {...(ctx.value as any)}></DownloadPackage>
                )}
              ></FormControl>
            </FormField>
          </FcForm>
        </SolidModal.Body>
      </SolidModal>
    </Page>
  );
};

export default PackageList;
